package cn.lsj.order.controller;

import cn.lsj.common.Commons;
import cn.lsj.common.entity.Payment;
import cn.lsj.payment.api.PaymentClient;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/order" + Commons.SERVER_VERSION)
@RefreshScope
public class OrderController {

    @Autowired
    private LoadBalancerClient loadBalancerClient;

    @Value("${test.name}")
    private String name;

    @Value("${test.port}")
    private Integer port;

    @Value("${test.fin}")
    private String fin;

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private PaymentClient paymentClient;

    @GetMapping("LoadBalancerClient")
    public ResponseEntity<Map<String, String>> LoadBalancerClient() {
        ServiceInstance order01 = loadBalancerClient.choose("order01");
        Map<String, String> res = new HashMap<>();
        res.put("port", order01.getPort() + "");
        res.put("host", order01.getHost() );
        return ResponseEntity.ok(res);
    }

    @SentinelResource(value = "loadbalancer", fallback = "loadbalancerFallback")
    @GetMapping("loadbalancer")
    public ResponseEntity<String> loadbalancer() {
        ResponseEntity<String> loadbalancer = paymentClient.loadbalancer();
        // 288 表示触发openfeign的降级了，这里抛出异常，可以触发Sentinel的降级
        if(loadbalancer.getStatusCodeValue() == 288) {
            throw  new RuntimeException();
        }
        return loadbalancer;
    }

    public ResponseEntity<String> loadbalancerFallback() {
        return ResponseEntity.ok("降级了");
    }


    @GetMapping("/feign")
    public ResponseEntity<Payment> aaaa() {
        return paymentClient.payment(111);
//        System.out.println(port);
//        System.out.println(fin);
//        return ResponseEntity.ok(name);
    }

    @GetMapping("/orderTimeout")
    public ResponseEntity<String> orderTimeout() throws InterruptedException {
        TimeUnit.SECONDS.sleep(10);
        return ResponseEntity.ok("成功");
    }

    @GetMapping("/feignTimeout")
    public ResponseEntity<Payment> feignTimeout() {
        return paymentClient.timeout();
    }

    @GetMapping("/fallback")
    public ResponseEntity<Payment> fallback() {
        ResponseEntity<Payment> payment = paymentClient.payment(111);
        return payment;
//        System.out.println(port);
//        System.out.println(fin);
//        return ResponseEntity.ok(name);
    }

    @GetMapping("/gzip")
    public long gzip() {
        long start = System.currentTimeMillis();
        ResponseEntity<List<Payment>> res = paymentClient.gzip();
        long end = System.currentTimeMillis();
        System.out.println(end - start);
        return end - start;
//        System.out.println(port);
//        System.out.println(fin);
//        return ResponseEntity.ok(name);
    }

    @GetMapping("/payment/{id}")
    public ResponseEntity<Payment> getPaymentById(@PathVariable("id") Integer id) {
        //发送http请求的，http://localhost:8081地址写死，去访问提供者行不行呢？
        String url = "http://payment/payment" + Commons.SERVER_VERSION + "/get/" + id;
        Payment payment = restTemplate.getForObject(url, Payment.class);
        return ResponseEntity.ok(payment);
    }
}
